(function($) {
	$.callLater = function(func /*,var-args params*/) {
		//Isolate non-callback parameters, and the last callback parameter.
		var params = null;
		var realCallback = null;
		
		if (arguments.length > 2) {
			params = Array.prototype.slice.call(arguments, 2, arguments.length - 1);
			realCallback = arguments[arguments.length - 1];
		}
		else {
			if (arguments.length == 2) {
				if (arguments[1].constructor != Function) {
					params = [ arguments[1] ];
				}
				else {
					params = [];
					realCallback = arguments[1];
				}
			}
			else {
				params = [];
			}
		}
		
		//Return a closure that, if called, will execute the async function.
		return (function(callback) {
			//Allow calling of real callback, as well as nextDelegate.
			function callbackWrapper() {
				if (realCallback) {
					realCallback.apply(this, arguments);
				}
				if (callback) {
					callback.apply(this, arguments);
				}
			}
			
			params.push(callbackWrapper);
			func.apply(null, params);
		});
	};
	
	$.synchronize = function(delegates) {
		var c = 0;
		function nextDelegate() {
			c++;
			if (c < delegates.length) {
				delegates[c](nextDelegate);
			}
		};
		

		delegates[c](nextDelegate);
	}
})(jQuery);